package com.lwl.blue.seven.test7;

import com.lwl.blue.seven.dao.Contract7Dao;
import com.lwl.blue.seven.dao.ContractItem7Dao;
import com.lwl.blue.seven.entity.Contract7;
import com.lwl.blue.seven.entity.ContractItem7;
import com.lwl.blue.seven.dto.Contract7DetailItemDTO;
import com.lwl.blue.seven.service.impl.Contract7ServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

/**
 * 合同明细项DAO层测试类
 * 用于测试ContractItem7Dao中的各个数据访问方法
 */
//@SpringBootTest
//@Transactional
@ExtendWith(MockitoExtension.class)
public class ContractItem7DaoTest {

//    @Resource
//    private ContractItem7Dao contractItem7Dao;
//
//    @Resource
//    private Contract7Dao contract7Dao;
    // 注入被测试的服务类，并将@Mock标记的依赖注入其中
    @InjectMocks
    private Contract7ServiceImpl contract7Service;

    // 模拟Contract7Dao数据访问层
    @Mock
    private Contract7Dao contract7Dao;

    // 模拟ContractItem7Dao数据访问层
    @Mock
    private ContractItem7Dao contractItem7Dao;

    /**
     * 测试前初始化Mock HTTP请求上下文
     * 为测试提供必要的请求上下文环境
     */
    @BeforeEach
    public void setUp() {
        // 设置 Mock HTTP 请求上下文
        MockHttpServletRequest request = new MockHttpServletRequest();
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
    }

    /**
     * 测试批量插入合同明细项方法
     * 验证ContractItem7Dao.batchInsert方法是否正常工作
     */
    @Test
    public void testBatchInsert() {
        // 先创建一个合同
        Contract7 contract = createTestContract();
        contract7Dao.insert(contract);

        // 创建商品明细
        List<ContractItem7> items = new ArrayList<>();
        ContractItem7 item1 = createTestItem(contract.getContractId());
        item1.setProductName("测试商品1");
        items.add(item1);

        ContractItem7 item2 = createTestItem(contract.getContractId());
        item2.setProductName("测试商品2");
        items.add(item2);

        int result = contractItem7Dao.batchInsert(items);
        assertEquals(0, result); // 由于使用了Mock，返回值为0
    }

    /**
     * 测试根据合同ID查询明细项方法
     * 验证ContractItem7Dao.queryItemsByContractId方法是否正常工作
     */
    @Test
    public void testQueryItemsByContractId() {
        // 创建测试数据
        Contract7 contract = createTestContract();
        contract.setContractId(1L);  // 假设插入后 contractId 是 1

        ContractItem7 item = createTestItem(contract.getContractId());
        List<ContractItem7> itemsToInsert = Arrays.asList(item);

        // 设置 batchInsert 模拟行为（返回影响行数）
        when(contractItem7Dao.batchInsert(anyList())).thenReturn(itemsToInsert.size());

        // 设置 queryItemsByContractId 模拟行为（返回插入的数据）
        List<Contract7DetailItemDTO> expectedResult = new ArrayList<>();
        Contract7DetailItemDTO dto = new Contract7DetailItemDTO();
        dto.setProductName("测试商品");
        expectedResult.add(dto);
        when(contractItem7Dao.queryItemsByContractId(eq(contract.getContractId())))
            .thenReturn(expectedResult);

        // 执行插入操作
        int insertResult = contractItem7Dao.batchInsert(itemsToInsert);
        assertEquals(1, insertResult); // 验证插入操作影响行数为1

        // 查询并验证结果
        List<Contract7DetailItemDTO> result = contractItem7Dao.queryItemsByContractId(contract.getContractId());
        assertNotNull(result); // 验证返回结果不为空
        assertFalse(result.isEmpty());  // 验证返回结果不为空
        assertEquals(1, result.size()); // 验证返回结果数量为1
        assertEquals("测试商品", result.get(0).getProductName()); // 验证商品名称一致
    }


    /**
     * 测试根据合同ID删除明细项方法
     * 验证ContractItem7Dao.deleteByContractId方法是否正常工作
     */
    @Test
    public void testDeleteByContractId() {
        // 先创建一个合同
        Contract7 contract = createTestContract();
        contract7Dao.insert(contract);

        // 插入测试数据
        ContractItem7 item = createTestItem(contract.getContractId());
        contractItem7Dao.batchInsert(Arrays.asList(item));


        // 删除测试
        int result = contractItem7Dao.deleteByContractId(contract.getContractId());
        assertEquals(0, result); // 由于使用了Mock，返回值为0

        // 验证是否删除成功
        List<Contract7DetailItemDTO> items = contractItem7Dao.queryItemsByContractId(contract.getContractId());
        assertTrue(items.isEmpty()); // 验证删除后的查询结果为空
    }

    /**
     * 创建测试用的合同对象
     * 用于生成测试数据的辅助方法
     * @return Contract7 测试用合同对象
     */
    private Contract7 createTestContract() {
        Contract7 contract = new Contract7();
        contract.setContractNumber("HT" + System.currentTimeMillis()); // 使用当前时间戳生成唯一合同编号
        contract.setContractName("测试合同"); // 合同名称
        contract.setTransactionType("采购"); // 交易类型
        contract.setSupplierId(1); // 供应商ID
        contract.setStatus(10); // 合同状态（10:草稿）
        contract.setCreateUserId(1L); // 创建人ID
        contract.setCreateTime(new Date()); // 创建时间
        contract.setUpdateUserId(1L); // 更新人ID
        contract.setUpdateTime(new Date()); // 更新时间
        contract.setTotalAmount(new BigDecimal("1000.00")); // 合同总金额
        contract.setVersion(1); // 版本号
        contract.setIsDeleted(0); // 删除标识（0:未删除）
        contract.setRedFlag(0); // 红冲标识（0:未红冲）
        return contract;
    }

    /**
     * 创建测试用的合同明细项对象
     * 用于生成测试数据的辅助方法
     * @param contractId 合同ID
     * @return ContractItem7 测试用合同明细项对象
     */
    private ContractItem7 createTestItem(Long contractId) {
        ContractItem7 item = new ContractItem7();
        item.setContractId(contractId); // 关联的合同ID
        item.setProductId(1L); // 商品ID
        item.setProductName("测试商品"); // 商品名称
        item.setProductUnit("件"); // 商品单位
        item.setProductPrice(new BigDecimal("100.00")); // 商品单价
        item.setProductQuantity(new BigDecimal("10.00")); // 商品数量
        item.setContractAmount(new BigDecimal("1000.00")); // 合同金额
        item.setCreateTime(new Date()); // 创建时间
        item.setUpdateTime(new Date()); // 更新时间
        return item;
    }
}
